#include "../include/db_manager.h"
#include "../include/user_manager.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <ctime>

// Static member definitions
std::map<int, std::map<std::string, std::string>> DBManager::users_;
std::map<std::pair<int, std::string>, double> DBManager::keyword_weights_;
std::vector<std::map<std::string, std::string>> DBManager::payments_;

// User structure for mock implementation
struct User {
    int id;
    std::string username;
    std::string password;
    std::string phone;
    std::string email;
    double balance;
    std::string created_at;
    std::string last_login;
};

// KeywordWeight structure for mock implementation
struct KeywordWeight {
    int user_id;
    std::string keyword;
    double weight;
    std::string created_at;
};

// Payment structure for mock implementation
struct Payment {
    int id;
    int user_id;
    double amount;
    std::string order_id;
    std::string status;
    std::string created_at;
    std::string completed_at;
};

DBManager::DBManager() {
    // Mock constructor
}

DBManager::~DBManager() {
    // Mock destructor
}

bool DBManager::initialize(const std::string& db_path) {
    // Mock initialization - always successful
    std::cout << "Mock database initialized with path: " << db_path << std::endl;
    return true;
}

bool DBManager::createUser(const std::string& username, const std::string& password, 
                          const std::string& phone, const std::string& email) {
    // Check if username already exists
    for (const auto& pair : users_) {
        if (pair.second.at("username") == username) {
            std::cerr << "Username already exists: " << username << std::endl;
            return false;
        }
    }
    
    // 加密密码
    UserManager user_manager;
    std::string encrypted_password = user_manager.encryptPassword(password);
    
    // Create new user
    int new_id = users_.empty() ? 1 : users_.rbegin()->first + 1;
    std::map<std::string, std::string> new_user;
    new_user["id"] = std::to_string(new_id);
    new_user["username"] = username;
    new_user["password"] = encrypted_password; // 存储加密后的密码
    new_user["phone"] = phone;
    new_user["email"] = email;
    new_user["balance"] = "0.0";
    new_user["created_at"] = getCurrentTimestamp();
    new_user["last_login"] = "";
    
    users_[new_id] = new_user;
    std::cout << "Created user: " << username << " with ID: " << new_id << " (password encrypted)" << std::endl;
    
    return true;
}

bool DBManager::authenticateUser(const std::string& username, const std::string& password, int& user_id) {
    for (const auto& pair : users_) {
        const auto& user = pair.second;
        if (user.at("username") == username) {
            // 使用UserManager进行密码验证
            UserManager user_manager;
            if (user_manager.verifyPassword(password, user.at("password"))) {
                user_id = pair.first;
                
                // Update last login time
                users_[user_id]["last_login"] = getCurrentTimestamp();
                
                std::cout << "User authenticated: " << username << " (password verified)" << std::endl;
                return true;
            } else {
                std::cerr << "Password verification failed for user: " << username << std::endl;
                return false;
            }
        }
    }
    
    std::cerr << "User not found: " << username << std::endl;
    return false;
}

bool DBManager::getUserInfo(int user_id, std::map<std::string, std::string>& user_info) {
    auto it = users_.find(user_id);
    if (it == users_.end()) {
        return false;
    }
    
    user_info = it->second;
    return true;
}

bool DBManager::updateUserBalance(int user_id, double amount) {
    auto it = users_.find(user_id);
    if (it == users_.end()) {
        return false;
    }
    
    double current_balance = std::stod(it->second["balance"]);
    it->second["balance"] = std::to_string(current_balance + amount);
    std::cout << "Updated balance for user " << user_id << " by " << amount << ", new balance: " << it->second["balance"] << std::endl;
    
    return true;
}

double DBManager::getUserBalance(int user_id) {
    auto it = users_.find(user_id);
    if (it == users_.end()) {
        return 0.0;
    }
    
    return std::stod(it->second["balance"]);
}

bool DBManager::setKeywordWeight(int user_id, const std::string& keyword, double weight) {
    // Create key for keyword_weights_ map
    auto key = std::make_pair(user_id, keyword);
    keyword_weights_[key] = weight;
    
    std::cout << "Set keyword weight for user " << user_id << ", keyword: " << keyword << ", weight: " << weight << std::endl;
    
    return true;
}

double DBManager::getKeywordWeight(int user_id, const std::string& keyword) {
    auto key = std::make_pair(user_id, keyword);
    auto it = keyword_weights_.find(key);
    if (it != keyword_weights_.end()) {
        return it->second;
    }
    
    return 1.0; // Default weight
}

std::map<std::string, double> DBManager::getKeywordsByUser(int user_id) {
    std::map<std::string, double> result;
    
    for (const auto& pair : keyword_weights_) {
        if (pair.first.first == user_id) {
            result[pair.first.second] = pair.second;
        }
    }
    
    return result;
}

bool DBManager::createPayment(int user_id, double amount, const std::string& order_id) {
    std::map<std::string, std::string> payment;
    payment["id"] = std::to_string(payments_.size() + 1);
    payment["user_id"] = std::to_string(user_id);
    payment["amount"] = std::to_string(amount);
    payment["order_id"] = order_id;
    payment["status"] = "pending";
    payment["created_at"] = getCurrentTimestamp();
    payment["completed_at"] = "";
    
    payments_.push_back(payment);
    std::cout << "Created payment: " << order_id << " for user " << user_id << ", amount: " << amount << std::endl;
    
    return true;
}

bool DBManager::updatePaymentStatus(const std::string& order_id, const std::string& status) {
    for (auto& payment : payments_) {
        if (payment["order_id"] == order_id) {
            payment["status"] = status;
            if (status == "completed") {
                payment["completed_at"] = getCurrentTimestamp();
            }
            std::cout << "Updated payment status: " << order_id << " to " << status << std::endl;
            return true;
        }
    }
    
    return false;
}

std::vector<std::map<std::string, std::string>> DBManager::getUserPayments(int user_id) {
    std::vector<std::map<std::string, std::string>> result;
    
    for (const auto& payment : payments_) {
        if (std::stoi(payment.at("user_id")) == user_id) {
            result.push_back(payment);
        }
    }
    
    return result;
}

bool DBManager::beginTransaction() {
    // Mock transaction - always successful
    return true;
}

bool DBManager::commitTransaction() {
    // Mock transaction - always successful
    return true;
}

bool DBManager::rollbackTransaction() {
    // Mock transaction - always successful
    return true;
}

bool DBManager::executeQuery(const std::string& query) {
    // Mock query execution - always successful
    std::cout << "Mock query executed: " << query << std::endl;
    return true;
}

bool DBManager::executeQueryWithResult(const std::string& query, std::vector<std::map<std::string, std::string>>& results) {
    // Mock query execution with results - returns empty results
    std::cout << "Mock query executed with results: " << query << std::endl;
    results.clear();
    return true;
}

std::string DBManager::sanitizeString(const std::string& str) {
    // Simple string sanitization for mock implementation
    std::string result = str;
    size_t pos = 0;
    while ((pos = result.find("'", pos)) != std::string::npos) {
        result.replace(pos, 1, "''");
        pos += 2;
    }
    return result;
}

std::string DBManager::getCurrentTimestamp() {
    auto now = std::time(nullptr);
    auto tm = *std::localtime(&now);
    
    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
    return oss.str();
}